﻿#include "ste_controller.h"
#include "ui_ste_controller.h"

STE_Controller::STE_Controller(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::STE_Controller)
{
    ui->setupUi(this);
    findFreePorts();
    serialPort = nullptr;
    QStringList title;
    title.append(QStringLiteral("时间"));
    title.append(QStringLiteral("事件"));
    title.append(QStringLiteral("上报设备"));
    ui->treeWidget->setHeaderLabels(title);
    ui->treeWidget_devicelist->setHeaderLabel(QStringLiteral("设备"));
    ui->group_ctrl->setEnabled(false);
    ui->group_comdbg->setEnabled(false);
    ui->group_enum->setEnabled(false);
    ui->group_typechange->setEnabled(false);
    ui->group_test->setEnabled(false);
    devicestringmapinit();
    QString type_name;
    QVariant type_key;
    QMap<quint8,QString>::iterator iter = devicemap.begin();
    while (iter != devicemap.end())
    {
        type_key.setValue<quint8>(iter.key());
        type_name = iter.value();
        ui->combo_typeold->addItem(type_name,type_key);
        ui->combo_typenew->addItem(type_name,type_key);
        ui->combo_targettype->addItem(type_name,type_key);
        iter++;
    }
}

STE_Controller::~STE_Controller()
{
    delete ui;
}

//寻找空闲状态串口
void STE_Controller::findFreePorts()
{
    ports.clear();
    ports = QSerialPortInfo::availablePorts();
    ui->combo_com->clear();
    for (int i = 0; i < ports.size(); ++i)
    {
        ui->combo_com->addItem(ports.at(i).portName());
    }
}

void STE_Controller::on_btn_refresh_clicked()
{
    findFreePorts();
}

void STE_Controller::on_btn_link_clicked()
{
    if(serialPort == nullptr)
    {   //Open Com
        QSerialPortInfo info = ports[ui->combo_com->currentIndex()];
        serialPort = new QSerialPort();
        serialPort->setPort(info);
        if (!this->serialPort->open(QIODevice::ReadWrite))
        {
            QMessageBox::warning(nullptr,"Error",QStringLiteral("串口打开失败！"));
            return;
        }
        serialPort->setBaudRate(115200);
        serialPort->setDataBits(QSerialPort::Data8);
        serialPort->setStopBits(QSerialPort::OneStop);
        serialPort->setParity(QSerialPort::NoParity);
        connect(serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));
        ui->textBrowser->clear();
        ui->btn_link->setText(QStringLiteral("断开"));
        ui->group_ctrl->setEnabled(true);
        ui->group_comdbg->setEnabled(true);
        ui->group_enum->setEnabled(true);
        ui->combo_com->setEnabled(false);
        ui->group_typechange->setEnabled(true);
        ui->group_test->setEnabled(true);
    }
    else
    {   //Close Com
        serialPort->clear();
        serialPort->close();
        delete serialPort;
        serialPort = nullptr;
        ui->btn_link->setText(QStringLiteral("连接"));
        ui->group_ctrl->setEnabled(false);
        ui->group_comdbg->setEnabled(false);
        ui->group_enum->setEnabled(false);
        ui->combo_com->setEnabled(true);
        ui->group_typechange->setEnabled(false);
        ui->group_test->setEnabled(false);
    }
}

//接收来自串口的信息
void STE_Controller::receiveInfo()
{
    QByteArray msg = serialPort->readAll();
    if(ui->checkBox_hex->isChecked())
        ui->textBrowser->insertPlainText(QString("[recieve]") + msg.toHex().data() + "\n");
    else
        ui->textBrowser->insertPlainText(QString("[recieve]") + msg + "\n");
    for(int i = 0;i<msg.size();i++)
        zigbee_handler(msg.at(i));
}

bool STE_Controller::zigbee_Calsum(ZigbeeRecDataType &chk)
{
    quint8 sum = 0;
    for(int i = 0;i<sizeof(ZigbeeRecDataType)-1;i++)
        sum += chk.buf[i];
    if(chk.data.sum == sum)
        return true;
    else
        return false;
}

void STE_Controller::zigbee_handler(quint8 ch)
{
    static quint8 step = 0;
    //zigbee_data
    if(ch == 0xB1 && step == 0)
      {
        zigbee_data.buf[0] = ch;
        step++;
      }
      else if(step>=1 && step<=8)
      {
        zigbee_data.buf[step] = ch;
        step++;
      }
      else if(step == 9)
      {
        zigbee_data.buf[step] = ch;
        if(zigbee_Calsum(zigbee_data))
          zigbee_infodisp(zigbee_data);
        step = 0;
      }
      else
        step = 0;
}

QString STE_Controller::devicetostring(quint8 type,quint8 num)
{
    QString devicetypestr;
    QString devicestr;
    if(devicemap.contains(type))
        devicetypestr = devicemap.find(type).value();
    else
        devicetypestr = QString::number(type,16) + QStringLiteral("设备");
    devicestr = QString::number(num) + QStringLiteral("号")+devicetypestr;
    return devicestr;
}

QString STE_Controller::parttostring(quint8 part)
{
    if(part == 0x02)
        return QStringLiteral("胸部");
    else if(part == 0x03)
        return QStringLiteral("头部");
    else if(part == 0x07)
        return QStringLiteral("手臂");
    else if(part == 0x08)
        return QStringLiteral("腿部");
    else
        return QStringLiteral("阵亡");    //用于靶类
}

QString STE_Controller::eventtostring(ZigbeeRecDataType &frame)
{
    QString src_device = devicetostring(frame.data.devicetype,frame.data.devicenum);
    QString dst_device = devicetostring(frame.data.remotetype,frame.data.remotenum);
    QString eventstr;
    switch(frame.data.type)
    {
    case 0x01:  //状态帧，发送状态代码0表示已经阵亡，1表示离开攻击区，3表示进入攻击区
        if(frame.data.datacode == 0x00)
        {
            if(frame.data.data[0])
                eventstr = QString("%1阵亡。").arg(src_device);
        }
        else if(frame.data.datacode == 0x02)
        {
            if(frame.data.data[0])
                eventstr = QString("%1攻击区内有敌人进入。").arg(src_device);
            else
                eventstr = QString("%1攻击区内敌人离开。").arg(src_device);
        }
        else
            eventstr = QString("%1发送了无法解析的状态帧。").arg(src_device);
        break;
    case 0x02:  //开火指示帧
        eventstr = QString("%1第%2次开火。").arg(src_device).arg(frame.data.datacode);
        break;
    case 0x03:  //命中指示帧
        eventstr = QString("%1被%2击中%3。").arg(src_device).arg(devicetostring(frame.data.data[0],frame.data.data[1])).arg(parttostring(frame.data.datacode));
        break;
    case 0x12:  //配置反馈帧
        if(frame.data.datacode == 0xFE)
        {
            eventstr = QString("%1在线。").arg(src_device);
            QTreeWidgetItem *item = new QTreeWidgetItem();
            QVariant type;
            QVariant num;
            type.setValue<quint8>(frame.data.devicetype);
            num.setValue<quint8>(frame.data.devicenum);
            item->setText(0,src_device);
            item->setData(0,Qt::UserRole,type);
            item->setData(1,Qt::UserRole,num);
            if(ui->treeWidget_devicelist->findItems(src_device,Qt::MatchFixedString).isEmpty())
                ui->treeWidget_devicelist->addTopLevelItem(item);
        }
        else
            eventstr = QString("配置成功。");
        break;
    }
    return eventstr;
}

void STE_Controller::zigbee_infodisp(ZigbeeRecDataType &frame)
{
    QTreeWidgetItem *item = new QTreeWidgetItem();
    item->setText(0,QTime::currentTime().toString("HH:mm:ss:zzz"));
    item->setText(1,eventtostring(frame));
    item->setText(2,devicetostring(frame.data.devicetype,frame.data.devicenum));
    ui->treeWidget->addTopLevelItem(item);
}


void STE_Controller::on_btn_send_clicked()
{
    QString str = ui->lineEdit->text();
    QByteArray msg = str.toLatin1().data();
    if(ui->checkBox_hex->isChecked())
        msg = msg.toHex().data();
    ui->textBrowser->insertPlainText(QString("[send]") + msg + "\n");
    serialPort->write(msg);
}

void STE_Controller::on_btn_clear_clicked()
{
    ui->treeWidget->clear();
    ui->textBrowser->clear();
    ui->treeWidget_devicelist->clear();
}

void STE_Controller::devicestringmapinit()
{
    devicemap.insert(0,QStringLiteral("基站"));
    devicemap.insert(1,QStringLiteral("路由器"));
    devicemap.insert(2,QStringLiteral("视频系统枪"));
    devicemap.insert(3,QStringLiteral("92枪"));
    devicemap.insert(4,QStringLiteral("95枪"));
    devicemap.insert(5,QStringLiteral("NP22枪"));
    devicemap.insert(6,QStringLiteral("警棍"));
    devicemap.insert(7,QStringLiteral("喷雾"));

    devicemap.insert(31,QStringLiteral("人像靶"));
    devicemap.insert(32,QStringLiteral("起倒靶"));
    devicemap.insert(33,QStringLiteral("摇摆靶"));
    devicemap.insert(34,QStringLiteral("自主靶"));

    devicemap.insert(36,QStringLiteral("起始靶"));
    devicemap.insert(37,QStringLiteral("终止靶"));

    devicemap.insert(51,QStringLiteral("作战服"));

    devicemap.insert(255,QStringLiteral("全部类型"));
}

void STE_Controller::on_btn_start_clicked()
{
    quint8 buf[] = {0xB2,0x11,0x00,0x00,0xFF,0xFF,0x00,0x01,0x00,0xC2};
    QByteArray msg((char *)buf,sizeof(buf));
    ui->textBrowser->insertPlainText(QString("[send]") + msg.toHex() + "\n");
    serialPort->write(msg);
}

void STE_Controller::on_btn_stop_clicked()
{
    quint8 buf[] = {0xB2,0x11,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0xC1};
    QByteArray msg((char *)buf,sizeof(buf));
    ui->textBrowser->insertPlainText(QString("[send]") + msg.toHex() + "\n");
    serialPort->write(msg);
}

void STE_Controller::on_btn_enum_clicked()
{
    quint8 buf[] = {0xB2,0x11,0x00,0x00,0xFF,0xFF,0xFE,0x00,0x00,0xBF};
    QByteArray msg((char *)buf,sizeof(buf));
    ui->treeWidget_devicelist->clear();
    ui->textBrowser->insertPlainText(QString("[send]") + msg.toHex() + "\n");
    serialPort->write(msg);
}

void STE_Controller::on_button_typechange_clicked()
{
    quint8 buf[] = {0xB2,0x11,0x00,0x00,0xFF,0xFF,0x02,0x00,0x00,0x00};
    buf[4] = ui->combo_typeold->currentData().value<quint8>();
    buf[5] = ui->spin_numold->value();
    buf[7] = ui->combo_typenew->currentData().value<quint8>();
    buf[8] = ui->spin_numnew->value();
    calChecksum(buf);
    if((buf[4] == 0x02 || buf[4] == 0x03) && (buf[7] == 0x02 || buf[7] == 0x03))
        ;   //允许
    else if((buf[4] == 31 || buf[4] == 36 || buf[4] == 37)
            && (buf[7] == 31 || buf[7] == 36 || buf[7] == 37))
        ;
    else if(buf[4] == 51 && buf[7] == 51)
        ;
    else
    {
        QMessageBox::information(NULL,QStringLiteral("非法指令"),QStringLiteral("不允许的类型转换！"));
        return;
    }
    QByteArray msg((char *)buf,sizeof(buf));
    ui->treeWidget_devicelist->clear();
    ui->textBrowser->insertPlainText(QString("[send]") + msg.toHex() + "\n");
    serialPort->write(msg);
}

void STE_Controller::calChecksum(quint8 data[])
{
    data[9] = 0;
    for(int i = 0;i<9;i++)
        data[9] += data[i];
}

void STE_Controller::on_button_test_clicked()
{
    quint8 buf[] = {0xB2,0x11,0x00,0x00,0xFF,0xFF,0x02,0x00,0x00,0x00};
    buf[4] = ui->combo_targettype->currentData().value<quint8>();
    buf[5] = ui->spin_targetnum->value();
    buf[6] = ui->spin_datacode->value();
    buf[7] = ui->spin_data0->value();
    buf[8] = ui->spin_data1->value();
    calChecksum(buf);
    QByteArray msg((char *)buf,sizeof(buf));
    ui->treeWidget_devicelist->clear();
    ui->textBrowser->insertPlainText(QString("[send]") + msg.toHex() + "\n");
    serialPort->write(msg);
}

void STE_Controller::on_treeWidget_devicelist_itemClicked(QTreeWidgetItem *item, int column)
{
    quint8 type = item->data(0,Qt::UserRole).value<quint8>();
    quint8 num = item->data(1,Qt::UserRole).value<quint8>();
    int index = ui->combo_typeold->findText(devicemap.find(type).value());
    if(index != -1)
    {
        ui->combo_typeold->setCurrentIndex(index);
        ui->combo_targettype->setCurrentIndex(index);
        ui->spin_numold->setValue(num);
        ui->spin_targetnum->setValue(num);
    }
}
